
/*--------------------------------------
	GugloPWN
--------------------------------------*/

// stock libs
#include <time.h>
#include <stdio.h>
#include <nds.h>
#include <fat.h>
#include <filesystem.h>


//my classes
#include "map.h"
#include "block.h"

void movcur();
void blkswi();
void setcam();
void draw_cursor();

void ed_base();
void ed_plat();
void ed_rail();
void ed_tags();
void ed_deco();
void ed_pole();
void ed_item();


map *m1;

int mx = 0;
int my = 0;

int x = 0;
int y = 0;
int z = 10;

int onum = 0;
int otype = 0;
int orot = 0;

int editmode = 0;
/*
0	Base
1	Platform
2	rail
3	Tags
4	Deco Objects
5	Poles
6	items
*/
int cammode = 0;
/*
0	isometric
1	x-axis
2	y-axis
3	z-axis
*/



int main() {


	// Setup the Main screen for 3D 
	videoSetMode(MODE_0_3D);
	
	//Set Video RAM
	vramSetBankA(VRAM_A_TEXTURE);
	vramSetBankB(VRAM_B_TEXTURE);
	vramSetBankC(VRAM_C_SUB_BG_0x06200000);
	vramSetBankD(VRAM_D_TEXTURE);

	//initialize the console on the subscreen
	consoleDemoInit();

	// initialize the geometry engine
	glInit();

	glEnable(GL_TEXTURE_2D);

	// setup the rear plane
	glClearColor(5,5,15,31); // BG must be opaque for AA to work
	glClearPolyID(0); // BG must have a unique polygon ID for AA to work
	glClearDepth(0x7FFF);
	

	// Set our viewport to be the same size as the screen
	glViewport(0,0,255,191);

	//Set camera and perspective
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	gluPerspective(70, 256.0 / 192.0, 0.1, 100);
	
	gluLookAt(  0.0, 0.0, 0.10,     //camera possition 
				0.15, 0.15, 0.0,    //look at
				0.0, 0.0, 1.0);     //up
					
	//ds specific, several attributes can be set here	
	glPolyFmt(POLY_ALPHA(0) | POLY_CULL_NONE);
	
	//Set the matrix mode to identity
	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();

	
	// Set the current matrix to be the model matrix
	glMatrixMode(GL_MODELVIEW);



	//FAT SD filesysyem init
	printf("\nInitializing FAT filesystem:");
	if (fatInitDefault()) {
		printf(" Success!");
	}
	else
	{
		printf(" Failed");
	}
	
	
	
	m1 = new map("demo");
	
	//while(1);
	
	while (1) 
	{
		//Clean up the Console
		consoleClear();
		
		//Change camera and edit modes
		scanKeys();
		blkswi();
		
		if ((keysDown() & KEY_TOUCH)) 
		{
			char filename[64];
			sprintf(filename,"%s%02d%02d","demo",mx,my);
			m1->writemapblock(mx,my,filename);
		}
		
		
		if ((keysDown() & KEY_START)) cammode++;
		if (cammode > 3) cammode = 0;
		
		if ((keysDown() & KEY_SELECT)) {editmode++; onum = 0; otype = 0;}
		if (editmode > 6) editmode = 0;
		
		printf("\nMap: %d %d",mx,my);
		printf("\nPos: %d %d %d",x,y,z);
		printf("\nObj num: %d",onum);
		printf("\nObj Type: %d",otype);
		
		
		
		if(editmode == 0)     {printf("\nEdit: Base    "); ed_base();}
		else if(editmode == 1){printf("\nEdit: Plat    "); ed_plat();}
		else if(editmode == 2){printf("\nEdit: Rail    "); ed_rail();}
		else if(editmode == 3){printf("\nEdit: Tags    "); ed_tags();}
		else if(editmode == 4){printf("\nEdit: Deco    "); ed_deco();}
		else if(editmode == 5){printf("\nEdit: Pole    "); ed_pole();}
		else if(editmode == 6){printf("\nEdit: Item    "); ed_item();}
		
		setcam();

		
		
		
	
		m1->drawmapcolmap(mx,my);
		//glPolyFmt(POLY_ALPHA(15) | POLY_CULL_NONE);
		m1->drawmap(mx,my);
		
		
		// flush to screen	
		glFlush(0);
		
		// wait for the screen to refresh
		swiWaitForVBlank();
	}
	
	return 0;
}

void blkswi()
{
	if(keysHeld() & KEY_R)
	{
		if ((keysDown() & KEY_LEFT)) mx--;
		if ((keysDown() & KEY_RIGHT)) mx++;
		if ((keysDown() & KEY_UP)) my++;
		if ((keysDown() & KEY_DOWN)) my--;
	}
	return;
}

void movcur()
{
	int spd = 1;
	if((keysHeld() & KEY_L)) spd = 4;
	
	if ((keysDown() & KEY_LEFT)) x-=spd;
	if ((keysDown() & KEY_RIGHT)) x+=spd;
	if ((keysDown() & KEY_UP)) y+=spd;
	if ((keysDown() & KEY_DOWN)) y-=spd;
	if ((keysDown() & KEY_B)) z-=spd;
	if ((keysDown() & KEY_X)) z+=spd;

	return;
}

void setcam()
{
	float px,py,pz;
	float dist = 5.0;
	float uy = 0.0, uz = 1.0;
	
	
	if(cammode == 0)
	{
		px = (float)x-dist;
		py = (float)y-dist;
		pz = (float)z+dist*4;
		printf("\nCam: Iso  ");
	}
	else if(cammode == 1)
	{
		px = (float)x-dist;
		py = (float)y;
		pz = (float)z;
		printf("\nCam: X    ");
	}
	else if(cammode == 2)
	{
		px = (float)x;
		py = (float)y-dist;
		pz = (float)z;
		printf("\nCam: Y    ");
	}
	else if(cammode == 3)
	{
		px = (float)x;
		py = (float)y;
		pz = (float)z+dist*4;
		printf("\nCam: Z    ");
		uy = 1.0;
		uz = 0.0;
	}
	
	

	glLoadIdentity();
	gluLookAt(  px/10, py/10, pz/40,	//camera possition 
				((float)x)/10.0, ((float)y)/10.0, ((float)z)/40.0,				//look at
				0.0, uy, uz);				//up
}

void ed_base()
{
	movcur();
	
	if (!(keysHeld() & KEY_Y))
	{
		if ((keysDown() & KEY_LEFT)) z = m1->getblockbase(mx,my,x,y);
		if ((keysDown() & KEY_RIGHT)) z = m1->getblockbase(mx,my,x,y);
		if ((keysDown() & KEY_UP)) z = m1->getblockbase(mx,my,x,y);
		if ((keysDown() & KEY_DOWN)) z = m1->getblockbase(mx,my,x,y);
	
		if ((keysDown() & KEY_B)) m1->setblockbase(mx,my,x,y,z);
		if ((keysDown() & KEY_X)) m1->setblockbase(mx,my,x,y,z);
	}
	else
	{
		if ((keysDown() & KEY_LEFT)) m1->setblockbase(mx,my,x,y,z);
		if ((keysDown() & KEY_RIGHT)) m1->setblockbase(mx,my,x,y,z);
		if ((keysDown() & KEY_UP)) m1->setblockbase(mx,my,x,y,z);
		if ((keysDown() & KEY_DOWN)) m1->setblockbase(mx,my,x,y,z);
	}
	
	//draw_cursor();
}

void ed_plat()
{
	movcur();
	
	if (!(keysHeld() & KEY_Y))
	{
		if ((keysDown() & KEY_LEFT)) z = m1->getblockplat(mx,my,x,y);
		if ((keysDown() & KEY_RIGHT)) z = m1->getblockplat(mx,my,x,y);
		if ((keysDown() & KEY_UP)) z = m1->getblockplat(mx,my,x,y);
		if ((keysDown() & KEY_DOWN)) z = m1->getblockplat(mx,my,x,y);
	
		if ((keysDown() & KEY_B)) m1->setblockplat(mx,my,x,y,z);
		if ((keysDown() & KEY_X)) m1->setblockplat(mx,my,x,y,z);
	}
	else
	{
		if ((keysDown() & KEY_LEFT)) m1->setblockplat(mx,my,x,y,z);
		if ((keysDown() & KEY_RIGHT)) m1->setblockplat(mx,my,x,y,z);
		if ((keysDown() & KEY_UP)) m1->setblockplat(mx,my,x,y,z);
		if ((keysDown() & KEY_DOWN)) m1->setblockplat(mx,my,x,y,z);
	}
	
	//draw_cursor();
}

void ed_rail()
{
	
	//Change the rail we are looking at
	if (!(keysHeld() & KEY_R))
	{
		if ((keysDown() & KEY_A)) {onum++; if (onum > 15) onum = 0;}
	}
	else
	{
		if ((keysDown() & KEY_A)) {onum--; if (onum < 0) onum = 15;}
	}
	
	if ((keysDown() & KEY_Y)) {otype++; if (otype > 1) otype = 0;}
	
	
	// Read that rail
	rail myrail = m1->getblockrail(mx, my, onum);
	
	//Set cursor to the rail
	if (otype == 0)
	{
		x = myrail.a.x;
		y = myrail.a.y;
		z = myrail.a.z;
	}
	else
	{
		x = myrail.b.x;
		y = myrail.b.y;
		z = myrail.b.z;
	}
	
	//Moce the cursor
	movcur();
	
	//Write the rail and print some UI text
	if (otype == 0)
	{
		myrail.a.x = x;
		myrail.a.y = y;
		myrail.a.z = z;
		
		m1->setblockrail(mx, my, onum, myrail);
		
		printf("\n> A  X: %02d Y: %02d Z: %02d",myrail.a.x,myrail.a.y,myrail.a.z);
		printf("\n  B  X: %02d Y: %02d Z: %02d",myrail.b.x,myrail.b.y,myrail.b.z);
	}
	else
	{
		myrail.b.x = x;
		myrail.b.y = y;
		myrail.b.z = z;
		
		m1->setblockrail(mx, my, onum, myrail);
		
		printf("\n  A  X: %02d Y: %02d Z: %02d",myrail.a.x,myrail.a.y,myrail.a.z);
		printf("\n> B  X: %02d Y: %02d Z: %02d",myrail.b.x,myrail.b.y,myrail.b.z);
	}
	
}

void ed_tags()
{
	//Change the Tag we are looking at
	if (!(keysHeld() & KEY_R))
	{
		if ((keysDown() & KEY_A)) {onum++; if (onum > 5) onum = 0;}
	}
	else
	{
		if ((keysDown() & KEY_A)) {onum--; if (onum < 0) onum = 5;}
	}
	
	// Read that tag
	tag mytag = m1->getblocktag(mx, my, onum);
	
	//Set cursor to the rail
	
	x = mytag.x;
	y = mytag.y;
	z = mytag.z;
	otype = mytag.size;
	orot = mytag.rot;

	//Moce the cursor
	movcur();
	if ((keysHeld() & KEY_R)) {if ((keysDown() & KEY_Y)) {otype++; if (otype > 3) otype = 0;}}
	else {if ((keysDown() & KEY_Y)) {orot++; if (orot > 3) orot = 0;}}
	
	//write the deco obj new location
	mytag.x = x;
	mytag.y = y;
	mytag.z = z;
	mytag.size = otype;
	mytag.rot = orot;
	m1->setblocktag(mx, my, onum, mytag);
	
	printf("\nObj rot: = %d",orot);
}

void ed_deco()
{
	//Change the Deco Obj we are looking at
	if (!(keysHeld() & KEY_R))
	{
		if ((keysDown() & KEY_A)) {onum++; if (onum > 15) onum = 0;}
	}
	else
	{
		if ((keysDown() & KEY_A)) {onum--; if (onum < 0) onum = 15;}
	}
	
	// Read that Deco
	deco mydeco = m1->getblockdeco(mx, my, onum);
	
	//Set cursor to the rail
	
	x = mydeco.x;
	y = mydeco.y;
	z = mydeco.z;
	otype = mydeco.type;
	orot = mydeco.rot;

	//Moce the cursor
	movcur();
	if ((keysHeld() & KEY_R)) {if ((keysDown() & KEY_Y)) {otype++; if (otype > 15) otype = 0;}}
	else {if ((keysDown() & KEY_Y)) {orot++; if (orot > 3) orot = 0;}}
	
	//write the deco obj new location
	mydeco.x = x;
	mydeco.y = y;
	mydeco.z = z;
	mydeco.type = otype;
	mydeco.rot = orot;
	m1->setblockdeco(mx, my, onum, mydeco);
	
	printf("\nObj rot: = %d",orot);
}

void ed_pole()
{
	//Change the Pole we are looking at
	if (!(keysHeld() & KEY_R))
	{
		if ((keysDown() & KEY_A)) {onum++; if (onum > 15) onum = 0;}
	}
	else
	{
		if ((keysDown() & KEY_A)) {onum--; if (onum < 0) onum = 15;}
	}
	
	// Read that Pole
	pole mypole = m1->getblockpole(mx, my, onum);
	
	//Set cursor to the pole
	x = mypole.x;
	y = mypole.y;
	z = mypole.z;
	
	movcur();
	
	//write the Pole's new location
	mypole.x = x;
	mypole.y = y;
	mypole.z = z;
	m1->setblockpole(mx, my, onum, mypole);
}

void ed_item()
{
}


void draw_cursor()
{

	glPolyFmt(POLY_ALPHA(31) | POLY_CULL_NONE);
	glColor3f(1.0f,0.0f,0.0f);
	glBegin(GL_QUADS);
		glVertex3f( ((float)x)/10, ((float)y)/10, ((float)z)/40);
		glVertex3f( ((float)(x+1))/10, ((float)y)/10, ((float)z)/40);
		glVertex3f( ((float)(x+1))/10, ((float)(y+1))/10, ((float)z)/40);
		glVertex3f( ((float)(x))/10, ((float)(y+1))/10, ((float)z)/40);
	glEnd();
	
	glColor3f(1.0f,1.0f,1.0f);
	
	return;
}





